package com.big.common.mybatis.util;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.big.common.core.result.AdvancedQuery;
import com.big.common.core.result.PageQuery;
import com.big.common.core.result.Query;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * mybatis分页工具类
 * </p>
 *
 * @author 山归岿
 * @create 2025-06-21-17:39
 */
public class MybatisPageUtils {


    /**
     * 创建MyBatis-Plus分页对象
     *
     * @param pageQuery 分页查询参数
     * @param <T>       查询条件类型
     * @return Page对象
     */
    public static <T> Page<T> createPage(PageQuery<?> pageQuery) {
        return new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
    }

    /**
     * 处理排序条件（支持多字段排序）
     *
     * @param queryWrapper  查询包装器
     * @param pageQuery     分页查询参数
     * @param defaultFields 默认排序字段
     * @param <T>           实体类型
     */
    public static <T> void handleOrderBy(QueryWrapper<T> queryWrapper, PageQuery<?> pageQuery, String... defaultFields) {
        if (CharSequenceUtil.isNotBlank(pageQuery.getOrderBy())) {
            String[] orderFields = pageQuery.getOrderBy().split(",");
            boolean isAsc = !"desc".equalsIgnoreCase(pageQuery.getOrderMode());

            for (String field : orderFields) {
                if (CharSequenceUtil.isNotBlank(field.trim())) {
                    queryWrapper.orderBy(true, isAsc, field.trim());
                }
            }
        } else if (defaultFields != null) {
            // 使用指定的默认排序字段
            for (String field : defaultFields) {
                if (CharSequenceUtil.isNotBlank(field)) {
                    queryWrapper.orderBy(true, true, field);
                }
            }
        }
    }

    /**
     * 处理排序条件（支持多字段排序）
     *
     * @param pageQuery     分页查询参数
     * @param defaultFields 默认排序字段
     * @param <T>           实体类型
     */
    public static <T> QueryWrapper<T> handleOrderBy(PageQuery<?> pageQuery, String... defaultFields) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        handleOrderBy(queryWrapper, pageQuery, defaultFields);
        return queryWrapper;
    }


    /**
     * 处理排序条件和高级查询（支持多字段排序）
     *
     * @param pageQuery     分页查询参数
     * @param defaultFields 默认排序字段
     * @param <T>           实体类型
     */
    public static <T> QueryWrapper<T> handleOrderByAndQuery(PageQuery<?> pageQuery, String... defaultFields) {
        QueryWrapper<T> queryWrapper = handleOrderBy(pageQuery, defaultFields);
        // 处理高级查询条件
        if (pageQuery.getAdvancedQuery() != null && pageQuery.getAdvancedQuery().getConditions() != null) {
            MybatisPageUtils.handleAdvancedQuery(queryWrapper, pageQuery.getAdvancedQuery());
        }
        return queryWrapper;
    }

    /**
     * 处理排序条件和高级查询（不带分页）
     *
     * @param query
     * @param <T>
     */
    public static <T> QueryWrapper<T> handleOrderByAndQuery(Query<?> query) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        if (query.getAdvancedQuery() != null && query.getAdvancedQuery().getConditions() != null) {
            MybatisPageUtils.handleAdvancedQuery(queryWrapper, query.getAdvancedQuery());
        }
        return queryWrapper;
    }

    /**
     * 处理高级查询条件
     *
     * @param queryWrapper  查询包装器
     * @param advancedQuery 高级查询条件
     * @param <T>           实体类型
     */
    public static <T> void handleAdvancedQuery(QueryWrapper<T> queryWrapper, AdvancedQuery advancedQuery) {
        List<AdvancedQuery.Condition> conditions = advancedQuery.getConditions();
        if (conditions == null || conditions.isEmpty()) {
            return;
        }

        // 获取逻辑操作符，默认为AND
        String logic = advancedQuery.getLogic();
        boolean isOr = "OR".equalsIgnoreCase(logic);

        // 如果是OR逻辑且有多个条件，需要使用nested方式
        if (isOr && conditions.size() > 1) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < conditions.size(); i++) {
                    AdvancedQuery.Condition condition = conditions.get(i);
                    if (i > 0) {
                        wrapper.or();
                    }
                    applyCondition(wrapper, condition);
                }
            });
        } else {
            // AND逻辑或单个条件，直接应用
            for (AdvancedQuery.Condition condition : conditions) {
                applyCondition(queryWrapper, condition);
            }
        }
    }

    /**
     * 应用单个查询条件
     *
     * @param queryWrapper 查询包装器
     * @param condition    查询条件
     * @param <T>          实体类型
     */
    private static <T> void applyCondition(QueryWrapper<T> queryWrapper, AdvancedQuery.Condition condition) {
        String field = condition.getField();
        String operator = condition.getOperator();
        Object value = condition.getValue();

        if (CharSequenceUtil.isBlank(field) || CharSequenceUtil.isBlank(operator)) {
            return;
        }

        // 将驼峰命名转换为下划线命名
        String columnName = camelToUnderscore(field);

        switch (operator) {
            case "eq":
                queryWrapper.eq(value != null, columnName, value);
                break;
            case "ne":
                queryWrapper.ne(value != null, columnName, value);
                break;
            case "like":
                queryWrapper.like(CharSequenceUtil.isNotBlank((String) value), columnName, value);
                break;
            case "notLike":
                queryWrapper.notLike(CharSequenceUtil.isNotBlank((String) value), columnName, value);
                break;
            case "likeLeft":
                queryWrapper.likeLeft(CharSequenceUtil.isNotBlank((String) value), columnName, value);
                break;
            case "likeRight":
                queryWrapper.likeRight(CharSequenceUtil.isNotBlank((String) value), columnName, value);
                break;
            case "gt":
                queryWrapper.gt(value != null, columnName, parseValue(value));
                break;
            case "ge":
                queryWrapper.ge(value != null, columnName, parseValue(value));
                break;
            case "lt":
                queryWrapper.lt(value != null, columnName, parseValue(value));
                break;
            case "le":
                queryWrapper.le(value != null, columnName, parseValue(value));
                break;
            case "in":
                if (value instanceof String) {
                    List<String> values = Arrays.asList(((String) value).split(","));
                    queryWrapper.in(!values.isEmpty(), columnName, values);
                } else if (value instanceof List) {
                    queryWrapper.in(!((List<?>) value).isEmpty(), columnName, (List<?>) value);
                }
                break;
            case "notIn":
                if (value instanceof String) {
                    List<String> values = Arrays.asList(((String) value).split(","));
                    queryWrapper.notIn(!values.isEmpty(), columnName, values);
                } else if (value instanceof List) {
                    queryWrapper.notIn(!((List<?>) value).isEmpty(), columnName, (List<?>) value);
                }
                break;
            case "isNull":
                queryWrapper.isNull(columnName);
                break;
            case "isNotNull":
                queryWrapper.isNotNull(columnName);
                break;
            default:
                // 默认使用等于
                queryWrapper.eq(value != null, columnName, value);
                break;
        }
    }

    /**
     * 处理分页查询中的高级查询条件
     *
     * @param queryWrapper 查询包装器
     * @param pageQuery    分页查询参数
     * @param <T>          实体类型
     */
    public static <T> void handlePageAdvancedQuery(QueryWrapper<T> queryWrapper, PageQuery<?> pageQuery) {
        if (pageQuery.getAdvancedQuery() != null && pageQuery.getAdvancedQuery().getConditions() != null) {
            handleAdvancedQuery(queryWrapper, pageQuery.getAdvancedQuery());
        }
    }

    /**
     * 将驼峰命名转换为下划线命名
     *
     * @param camelCase 驼峰命名字符串
     * @return 下划线命名字符串
     */
    private static String camelToUnderscore(String camelCase) {
        if (StrUtil.isBlank(camelCase)) {
            return camelCase;
        }
        return camelCase.replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase();
    }

    /**
     * 解析值，处理日期时间类型
     *
     * @param value 原始值
     * @return 解析后的值
     */
    private static Object parseValue(Object value) {
        if (value == null) {
            return null;
        }

        if (value instanceof String strValue) {

            // 尝试解析为日期时间
            if (strValue.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")) {
                return LocalDateTime.parse(strValue, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }

            // 尝试解析为日期
            if (strValue.matches("\\d{4}-\\d{2}-\\d{2}")) {
                return LocalDate.parse(strValue, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            }
        }

        return value;
    }

}
